

#include "Buffer.hpp"
#include <sys/uio.h>
#include <unistd.h>


namespace zephyr {

ssize_t Buffer::readFd(int fd, int *saveErrno) {
    char extrabuf[65536] = {0}; // 64kb
    
    struct iovec vec[2];
    const size_t writable = writableBytes();

    // 指向可写区域
    vec[0].iov_base = begin() + m_writeIndex;
    vec[0].iov_len = writable;
    // 指向栈空间
    vec[1].iov_base = extrabuf;
    vec[1].iov_len = sizeof(extrabuf);

    // when there is enough space in this buffer, don't read into extrabuf.
    // when extrabuf is used, we read 128k-1 bytes at most.
    // 这里之所以说最多128k-1字节，是因为若writable为64k-1，那么需要两个缓冲区 第一个64k-1 第二个64k 所以做多128k-1
    // 如果第一个缓冲区>=64k 那就只采用一个缓冲区 而不使用栈空间extrabuf[65536]的内容
    const int iovcnt = (writable < sizeof(extrabuf)) ? 2 : 1;
    const ssize_t n = ::readv(fd, vec, iovcnt);

    if (n < 0) {
        *saveErrno = errno;
    } else if (n <= writable) {
        m_writeIndex += n;
    } else {
        m_writeIndex = m_buffer.size();
        // 将栈上缓冲区的数据移动到对象缓冲区中
        append(extrabuf, n - writable);
    }
    return n;
}

ssize_t Buffer::writeFd(int fd, int *saveErrno) {
    ssize_t n = ::write(fd, peek(), readableBytes());
    if (n < 0) {
        *saveErrno = errno;
    }
    return n;
}

}